home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 22
/
Cream of the Crop 22.iso
/
os2
/
ext2_200.zip
/
EXT2_SRC.ZIP
/
32BITS
/
EXT2-OS2
/
FSD32
/
FS32_FSC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-21
|
21KB
|
582 lines
//
// $Header: D:/32bits/ext2-os2/fsd32/RCS/fs32_fsctl.c,v 1.1 1996/09/21 22:25:12 Willm Exp Willm $
//
// 32 bits Linux ext2 file system driver for OS/2 WARP - Allows OS/2 to
// access your Linux ext2fs partitions as normal drive letters.
// Copyright (C) 1995, 1996 Matthieu WILLM
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifdef __IBMC__
#pragma strings(readonly)
#endif
#define INCL_DOS
#define INCL_DOSERRORS
#define INCL_NOPMAPI
#include <os2.h>
#include <string.h>
#include <os2/types.h>
#include <os2/StackToFlat.h>
#include <linux/fs.h>
#include <os2/os2proto.h>
#include <os2/fsd32.h>
#include <os2/fsh32.h>
#include <os2/DevHlp32.h>
#include <os2/log.h>
#include <os2/trace.h>
#include <os2/errors.h>
#include <os2/files.h>
#include <os2/volume.h>
#include <linux/fs_proto.h>
#include <linux/stat.h>
#include <os2/vfsapi.h>
#include <os2/ifsdbg.h>
/*
* Error messages to return for func. FSCTL_FUNC_NEW_INFO
*/
static struct fsctl_msg ext2_os2_magic = {sizeof(magic_msg), magic_msg};
static struct fsctl_msg ext2_os2_default = {sizeof(default_msg), default_msg};
int fsctl_func_new_info(struct fs32_fsctl_parms *parms) {
int rc, rc2;
char *pParm;
char *pData;
unsigned short *pLenParmOut;
unsigned short *pLenDataOut;
char lock_1[12];
char lock_2[12];
char lock_3[12];
char lock_4[12];
unsigned long PgCount;
short error;
if ((rc = DevHlp32_VirtToLin(parms->pParm, __StackToFlat(&pParm))) == NO_ERROR) {
if ((rc = DevHlp32_VirtToLin(parms->pData, __StackToFlat(&pData))) == NO_ERROR) {
if ((rc = DevHlp32_VirtToLin(parms->plenDataOut, __StackToFlat(&pLenDataOut))) == NO_ERROR) {
if ((rc = DevHlp32_VirtToLin(parms->plenParmOut, __StackToFlat(&pLenParmOut))) == NO_ERROR) {
rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY, pParm, sizeof(short), (void *)-1, __StackToFlat(lock_1), __StackToFlat(&PgCount));
if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
error = *((short *)pParm);
rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, pData, sizeof(struct fsctl_msg), (void *)-1, __StackToFlat(lock_2), __StackToFlat(&PgCount));
if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
if (error == NO_ERROR) {
memcpy(pData, &ext2_os2_magic, sizeof(ext2_os2_magic));
} else {
memcpy(pData, &ext2_os2_default, sizeof(ext2_os2_default));
}
rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, pLenDataOut, sizeof(short), (void *)-1, __StackToFlat(lock_3), __StackToFlat(&PgCount));
if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
*pLenDataOut = sizeof(struct fsctl_msg);
rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, pLenParmOut, sizeof(short), (void *)-1, __StackToFlat(lock_4), __StackToFlat(&PgCount));
if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
*pLenParmOut = 0;
rc = NO_ERROR;
if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_4))) == NO_ERROR) {
} else {
rc = rc2;
}
}
if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_3))) == NO_ERROR) {
} else {
rc = rc2;
}
}
if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_2))) == NO_ERROR) {
} else {
rc = rc2;
}
}
if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_1))) == NO_ERROR) {
} else {
rc = rc2;
}
}
}
}
}
}
return rc;
}
int ifsdbg_open(struct fs32_fsctl_parms *parms) {
int rc;
if (BufOpen == 0) {
BufOpen = 1;
if (BufPtr == 0) {
fsh32_semset(&BufSem);
}
rc = NO_ERROR;
} else {
rc = ERROR_DEVICE_IN_USE;
}
return rc;
}
int ifsdbg_close(struct fs32_fsctl_parms *parms) {
int rc;
if (BufOpen == 1) {
BufOpen = 0;
rc = NO_ERROR;
} else {
rc = ERROR_NOT_READY;
}
return rc;
}
int ifsdbg_read(struct fs32_fsctl_parms *parms) {
int rc, rc2;
char *pData;
unsigned short *plenDataOut;
char lock_1[12];
char lock_2[12];
unsigned long PgCount;
if (BufOpen == 1) {
if ((rc = DevHlp32_VirtToLin(parms->pData, __StackToFlat(&pData))) == NO_ERROR) {
if ((rc = DevHlp32_VirtToLin(parms->plenDataOut, __StackToFlat(&plenDataOut))) == NO_ERROR) {
rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, pData, parms->lenData, (void *)-1, __StackToFlat(lock_1), __StackToFlat(&PgCount));
if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, plenDataOut, sizeof(short), (void *)-1, __StackToFlat(lock_2), __StackToFlat(&PgCount));
if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
/*************************************************************/
/*** If no data is present, simply set the semaphore ***/
/*************************************************************/
if (BufPtr == 0) {
*plenDataOut = 0;
rc = NO_ERROR;
} else {
/*************************************************************/
/*** If the log data is smaller than the requested amount ***/
/*** we copy them all ***/
/*************************************************************/
if (BufPtr < parms->lenData) {
memcpy(pData, BufMsg, BufPtr + 1);
*plenDataOut = BufPtr + 1;
BufPtr = 0;
rc = NO_ERROR;
}
}
/*************************************************************/
/*** We set the log semaphore ***/
/*** ext2-os2.exe will wait on it until some more data is ***/
/*** present ***/
/*************************************************************/
fsh32_semset(&BufSem);
if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_2))) == NO_ERROR) {
} else {
rc = rc2;
}
}
if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_1))) == NO_ERROR) {
} else {
rc = rc2;
}
}
}
}
} else {
rc = ERROR_NOT_READY;
}
return rc;
}
int ext2_os2_bdflush(struct fs32_fsctl_parms *parms) {
/*
* We should never return from this call.
*/
sys_bdflush(0, 0);
return NO_ERROR; // makes compiler happy
}
int ext2_os2_shrink_cache(struct fs32_fsctl_parms *parms) {
while(1) {
if (buffermem)
shrink_buffers(3);
DevHlp32_ProcBlock((unsigned long)ext2_os2_shrink_cache, 10000, 1);
}
return NO_ERROR; // makes compiler happy
}
int ext2_os2_getdata(struct fs32_fsctl_parms *parms) {
int rc, rc2;
char *pData;
unsigned short *plenDataOut;
char lock_1[12];
char lock_2[12];
unsigned long PgCount;
struct ext2_os2_data *d;
if ((rc = DevHlp32_VirtToLin(parms->pData, __StackToFlat(&pData))) == NO_ERROR) {
if ((rc = DevHlp32_VirtToLin(parms->plenDataOut, __StackToFlat(&plenDataOut))) == NO_ERROR) {
// rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, pData, sizeof(struct ext2_os2_data), (void *)-1, __StackToFlat(lock_1), __StackToFlat(&PgCount));
// if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
// rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, plenDataOut, sizeof(short), (void *)-1, __StackToFlat(lock_2), __StackToFlat(&PgCount));
// if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
d = (struct ext2_os2_data *)pData;
/*
* Buffers statistics
*/
d->b.buffer_mem = buffermem;
d->b.cache_size = cache_size;
d->b.nr_buffer_heads = nr_buffer_heads;
memcpy(&(d->b.nr_free), nr_free, sizeof(nr_free));
memcpy(&(d->b.nr_buffers_type), nr_buffers_type, sizeof(nr_buffers_type));
/*
* I-nodes statistics
*/
d->i.nr_inodes = nr_inodes;
d->i.nr_free_inodes = nr_free_inodes;
d->i.nr_iget = nr_iget;
d->i.nr_iput = nr_iput;
/*
* Files statistics
*/
d->f.nhfiles = nr_files;
d->f.nfreehfiles = nr_free_files;
d->f.nusedhfiles = nr_used_files;
/*
* Swapper statistics
*/
d->s.nr_total_pgin = nr_total_pgin;
d->s.nr_total_pgout = nr_total_pgout;
d->s.nr_pgin = nr_pgin;
d->s.nr_pgout = nr_pgout;
nr_pgin = 0;
nr_pgout = 0;
*plenDataOut = sizeof(struct ext2_os2_data);
// if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_2))) == NO_ERROR) {
// } else {
// rc = rc2;
// }
// }
// if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_1))) == NO_ERROR) {
// } else {
// rc = rc2;
// }
// }
}
}
return rc;
}
int ext2_os2_sync(struct fs32_fsctl_parms *parms) {
int rc;
// struct vpfsi32 *pvpfsi;
// struct vpfsd32 *pvpfsd;
int i;
struct super_block *sb;
//
// VFSAPI Library entry point : this is the vfs_sync() routine (standart sync() system call)
// Input :
// pData (ignored)
// pParm (ignored)
// Output :
// pData (ignored)
// pParm (ignored)
//
if (Read_Write) {
#if 0
for (i = 0 ; i < NB_MAX_VOLS ; i++) {
if (volglobdat.listvol[i].status == VOL_STATUS_MOUNTED) {
// fsh32_getvolparm(volglobdat.listvol[i].hVPB, __StackToFlat(&pvpfsi16), __StackToFlat(&pvpfsd16));
sb = getvolume(volglobdat.listvol[i].hVPB);
if (sb) {
kernel_printf("Flushing volume 0x%0X", volglobdat.listvol[i].hVPB);
sync_buffers(sb->s_dev, 0);
sync_inodes(sb->s_dev);
sync_buffers(sb->s_dev, 0);
}
}
}
#endif
sys_sync();
rc = NO_ERROR;
} else {
rc = ERROR_WRITE_PROTECT;
}
return rc;
}
int ext2_os2_stat(struct fs32_fsctl_parms *parms) {
int rc, rc2;
char *pData;
unsigned short *plenDataOut;
char lock_1[12];
char lock_2[12];
unsigned long PgCount;
struct ext2_os2_data *d;
union argdat32 *pArgdat;
struct super_block *sb;
if (parms->iArgType == FSCTL_ARG_CURDIR) {
if (parms->lenData >= sizeof(struct new_stat)) {
if ((rc = DevHlp32_VirtToLin(parms->pArgdat, __StackToFlat(&pArgdat))) == NO_ERROR) {
if ((rc = DevHlp32_VirtToLin(parms->pData, __StackToFlat(&pData))) == NO_ERROR) {
if ((rc = DevHlp32_VirtToLin(parms->plenDataOut, __StackToFlat(&plenDataOut))) == NO_ERROR) {
rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, pData, sizeof(struct new_stat), (void *)-1, __StackToFlat(lock_1), __StackToFlat(&PgCount));
if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, plenDataOut, sizeof(short), (void *)-1, __StackToFlat(lock_2), __StackToFlat(&PgCount));
if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
//
// VFSAPI Library entry point : this is the vfs_stat() routine (standart stat() system call)
// Input :
// pData must point to a buffer large enough to hold struct vfs_stat
// pParm (ignored)
// Output :
// pData contains the struct vfs_stat if success, or garbage if failed
// pParm (ignored)
//
*plenDataOut = sizeof(struct new_stat);
kernel_printf("FS_FSCTL(EXT2_OS2_STAT) - Path is %s", pArgdat->cd.pPath);
{
struct file *f;
struct new_stat *s;
unsigned long DOSmode;
//
// Gets the superblock
//
sb = getvolume(pArgdat->cd.pcdfsi->cdi_hVPB);
DOSmode = (is_case_retensive() ? OPENMODE_DOSBOX : 0);
if ((f = _open_by_name(sb, pArgdat->cd.pPath, OPENMODE_READONLY | DOSmode)) != NULL) {
s = (struct new_stat *)pData;
memset(s, 0, sizeof(struct new_stat));
s->st_dev = f->f_inode->i_dev;
s->st_ino = f->f_inode->i_ino;
s->st_mode = f->f_inode->i_mode;
s->st_nlink = f->f_inode->i_nlink;
s->st_uid = f->f_inode->i_uid;
s->st_gid = f->f_inode->i_gid;
s->st_rdev = f->f_inode->i_rdev;
s->st_size = f->f_inode->i_size;
// if (inode->i_pipe)
// tmp.st_size = PIPE_SIZE(*inode);
s->st_atime = f->f_inode->i_atime;
s->st_mtime = f->f_inode->i_mtime;
s->st_ctime = f->f_inode->i_ctime;
s->st_blocks = f->f_inode->i_blocks;
s->st_blksize = f->f_inode->i_blksize;
vfs_close(f);
} else {
kernel_printf("FS_FSCTL() - path %s not found", pArgdat->cd.pPath);
return rc;
}
}
if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_2))) == NO_ERROR) {
} else {
rc = rc2;
}
}
if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_1))) == NO_ERROR) {
} else {
rc = rc2;
}
}
}
}
}
} else {
rc = ERROR_BUFFER_OVERFLOW;
}
} else {
rc = ERROR_INVALID_PARAMETER;
}
return rc;
}
int ext2_os2_fstat(struct fs32_fsctl_parms *parms) {
int rc, rc2;
char *pData;
unsigned short *plenDataOut;
char lock_1[12];
char lock_2[12];
unsigned long PgCount;
struct ext2_os2_data *d;
union argdat32 *pArgdat;
struct super_block *sb;
if (parms->iArgType == FSCTL_ARG_FILEINSTANCE) {
if (parms->lenData >= sizeof(struct new_stat)) {
if ((rc = DevHlp32_VirtToLin(parms->pArgdat, __StackToFlat(&pArgdat))) == NO_ERROR) {
if ((rc = DevHlp32_VirtToLin(parms->pData, __StackToFlat(&pData))) == NO_ERROR) {
if ((rc = DevHlp32_VirtToLin(parms->plenDataOut, __StackToFlat(&plenDataOut))) == NO_ERROR) {
rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, pData, sizeof(struct new_stat), (void *)-1, __StackToFlat(lock_1), __StackToFlat(&PgCount));
if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
rc = DevHlp32_VMLock(VMDHL_LONG | VMDHL_VERIFY | VMDHL_WRITE, plenDataOut, sizeof(short), (void *)-1, __StackToFlat(lock_2), __StackToFlat(&PgCount));
if ((rc == NO_ERROR) || (rc == ERROR_NOBLOCK)) {
//
// VFSAPI Library entry point : this is the vfs_fstat() routine (standart fstat() system call)
// Input :
// pData must point to a buffer large enough to hold struct vfs_stat
// pParm (ignored)
// Output :
// pData contains the struct vfs_stat if success, or garbage if failed
// pParm (ignored)
//
*plenDataOut = sizeof(struct new_stat);
{
struct new_stat *s;
struct inode *inode;
inode = pArgdat->sf.psffsd->f->f_inode;
s = (struct new_stat *)pData;
memset(s, 0, sizeof(struct new_stat));
s->st_dev = inode->i_dev;
s->st_ino = inode->i_ino;
s->st_mode = inode->i_mode;
s->st_nlink = inode->i_nlink;
s->st_uid = inode->i_uid;
s->st_gid = inode->i_gid;
s->st_rdev = inode->i_rdev;
s->st_size = inode->i_size;
// if (inode->i_pipe)
// tmp.st_size = PIPE_SIZE(*inode);
s->st_atime = inode->i_atime;
s->st_mtime = inode->i_mtime;
s->st_ctime = inode->i_ctime;
s->st_blocks = inode->i_blocks;
s->st_blksize = inode->i_blksize;
}
rc = NO_ERROR;
if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_2))) == NO_ERROR) {
} else {
rc = rc2;
}
}
if ((rc2 = DevHlp32_VMUnlock(__StackToFlat(lock_1))) == NO_ERROR) {
} else {
rc = rc2;
}
}
}
}
}
} else {
rc = ERROR_BUFFER_OVERFLOW;
}
} else {
rc = ERROR_INVALID_PARAMETER;
}
}
/*
* struct fs32_fsctl_parms {
* PTR16 plenDataOut;
* unsigned short lenData;
* PTR16 pData;
* PTR16 plenParmOut;
* unsigned short lenParm;
* PTR16 pParm;
* unsigned short func;
* unsigned short iArgType;
* PTR16 pArgdat;
* };
*/
int FS32ENTRY fs32_fsctl(struct fs32_fsctl_parms *parms) {
int rc;
parms = __StackToFlat(parms);
switch (parms->func) {
case FSCTL_FUNC_NEW_INFO :
rc = fsctl_func_new_info(parms);
break;
case IFSDBG_OPEN :
rc = ifsdbg_open(parms);
break;
case IFSDBG_CLOSE :
rc = ifsdbg_close(parms);
break;
case IFSDBG_READ :
rc = ifsdbg_read(parms);
break;
case EXT2_OS2_BDFLUSH :
rc = ext2_os2_bdflush(parms);
break;
case EXT2_OS2_SHRINK_CACHE :
rc = ext2_os2_shrink_cache(parms);
break;
case EXT2_OS2_GETDATA :
rc = ext2_os2_getdata(parms);
break;
case EXT2_OS2_SYNC :
rc = ext2_os2_sync(parms);
break;
case EXT2_OS2_STAT :
rc = ext2_os2_stat(parms);
break;
case EXT2_OS2_FSTAT :
rc = ext2_os2_fstat(parms);
break;
default :
rc = ERROR_NOT_SUPPORTED;
break;
}
return rc;
}